package com.ncmem.up6.database;

import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.ParseException;
import java.util.List;

import com.google.gson.Gson;

import com.ncmem.up6.database.mongo.MongoFile;
import com.ncmem.up6.database.mysql.MySQLFile;
import com.ncmem.up6.database.odbc.OdbcFile;
import com.ncmem.up6.database.oracle.OracleFile;
import com.ncmem.up6.database.postpresql.PostpreSqlFile;
import com.ncmem.up6.model.FileInf;
import com.ncmem.up6.sql.*;
import com.ncmem.up6.utils.ConfigReader;
import com.ncmem.up6.utils.DataBaseType;

/**
 * Created by Administrator on 2021/1/6.
 */

/*
 * 原型
*/
public class DBFile {

    public DBFile()
    {
    }

    public SqlTable table(){
        return  SqlTable.build("up6_files");
    }

    public static DBFile build(){
        DataBaseType dt = ConfigReader.dbType();

        if( dt == DataBaseType.MySQL ) return new MySQLFile();
        if( dt == DataBaseType.Oracle ||
                dt == DataBaseType.DMDB) return new OracleFile();
        if( dt == DataBaseType.KingBase ) return new OdbcFile();
        if( dt == DataBaseType.MongoDB ) return new MongoFile();
        if( dt == DataBaseType.PostgreSQL ) return new PostpreSqlFile();
        return new DBFile();
    }

    /**
     * 从up6_files表中加载未上传完的文件列表
     * @param f_uid
     * @return
     * @throws SQLException
     * @throws InstantiationException
     * @throws ParseException
     * @throws IllegalAccessException
     */
    public String unCompletes(String f_uid) throws SQLException, InstantiationException, ParseException, IllegalAccessException {
         List<FileInf> files = this.table().reads(FileInf.build(),
                SqlWhere.build()
                        .eq("f_deleted",false)
                        .eq("f_fdChild",false)
                        .eq("f_complete",false)
                        .eq("f_scan",false)
        );

        Gson g = new Gson();
        return g.toJson( files);//bug:arrFiles为空时，此行代码有异常
    }

    public FileInf read(String id) throws ParseException, IllegalAccessException, SQLException {
        return this.table().readOne(FileInf.build(),
                SqlWhere.build().eq("f_id",id));
    }

    public FileInf read(String pathRel,String id,String uid) throws ParseException, IllegalAccessException, SQLException {
        return this.table().readOne(FileInf.build(),
                "f_id,f_pid,f_pidRoot,f_pathSvr,f_pathRel",
                SqlWhere.build()
                        .eq("f_pathRel", pathRel)
                        .eq("f_deleted", false)
                        .eq("f_uid", uid)
                        .ineq("f_id", id)
        );
    }

    public FileInf exist_file(String md5) throws ParseException, IllegalAccessException, SQLException {
        return this.table()
                .readOne(FileInf.build(),
                SqlWhere.build()
                        .eq("f_md5",md5)
                        .eq("f_complete",true)
                );

    }

    /**
     * 增加一条数据，在f_create中调用。
     * 文件名称，本地路径，远程路径，相对路径都使用原始字符串。
     * d:\soft\QQ2012.exe
     * @param f
     * @return
     */
    public void Add(FileInf f) throws ParseException, IllegalAccessException, SQLException {
        this.table().insert(f);
    }

    /**
     * 添加子目录
     * @param f
     */
    public void addFolderChild(FileInf f) throws ParseException, IllegalAccessException, SQLException {
        SqlTable.build("up6_folders").insert(f);
    }

    /**
     * 清空文件表，文件夹表数据。
     */
    public void clear() throws SQLException {
        this.table().clear();
        SqlTable.build("up6_folders").clear();
    }

    public void complete(String id,String uid) throws ParseException, IllegalAccessException, SQLException {
        this.table().update(
                SqlSeter.build()
                        .sql("f_perSvr='100%'")
                        .sql("f_lenSvr=f_lenLoc")
                        .set("f_complete",true)
                        .set("f_scan",true),
                SqlWhere.build()
                        .eq("f_id",id)
                        .eq("f_uid",uid)
        );
    }

    /// <summary>
    /// 更新上传进度
    /// </summary>
    ///<param name="f_uid">用户ID</param>
    ///<param name="f_id">文件ID</param>
    ///<param name="f_pos">文件位置，大小可能超过2G，所以需要使用long保存</param>
    ///<param name="f_lenSvr">已上传长度，文件大小可能超过2G，所以需要使用long保存</param>
    ///<param name="f_perSvr">已上传百分比</param>
    public boolean f_process(String uid,String f_id,long offset,long f_lenSvr,String f_perSvr) throws ParseException, IllegalAccessException, SQLException {
        this.table().update(
                SqlSeter.build()
                        .set("f_pos",offset)
                        .set("f_lenSvr",f_lenSvr)
                        .set("f_perSvr",f_perSvr),
                SqlWhere.build()
                        .eq("f_id",f_id)
                        .eq("f_uid",uid)
        );

        return true;
    }

    /// <summary>
    /// 删除一条数据，并不真正删除，只更新删除标识。
    /// </summary>
    /// <param name="f_uid"></param>
    /// <param name="f_id"></param>
    public void Delete(String f_uid,String f_id) throws ParseException, IllegalAccessException, SQLException {
        this.table().update(
                SqlSeter.build().set("f_deleted",true),
                SqlWhere.build()
                        .eq("f_id",f_id)
                        .eq("f_uid",f_uid)
        );
    }

    public void delete(String pathRel,String uid,String id) throws ParseException, IllegalAccessException, SQLException {
        this.table().update(
                SqlSeter.build().set("f_deleted",true),
                SqlWhere.build()
                        .eq("f_uid",uid)
                        .eq("f_pathRel",pathRel)
                        .eq("f_fdTask",false)
                        .ineq("f_id",id)
        );
    }

    public boolean existSameFile(String name,String pid)
    {
        SqlWhereMerge swm = new SqlWhereMerge();
        swm.equal("f_nameLoc", name.trim());
        swm.equal("f_pid", pid.trim());
        swm.equal("f_deleted", 0);

        SqlExec se = new SqlExec();
        return se.count("up6_files", swm.to_sql())>0;
    }

    /**
     * 更新子文件路径
     * @param pathRelOld
     * @param pathRelNew
     */
    public void updatePathRel(String pathRelOld,String pathRelNew)
    {
        //更新子文件路径
        String sql = String.format("update up6_files set f_pathRel=REPLACE(f_pathRel,'%s/','%s/') where CHARINDEX('%s/',f_pathRel)=1",
                pathRelOld,
                pathRelNew,
                pathRelOld
        );

        SqlExec se = new SqlExec();
        se.exec(sql);

    }

    //批量添加
    public void addBatch(List<FileInf> arr) throws SQLException, ParseException, IllegalAccessException {
        for (FileInf a : arr) {
            a.object_id = a.getObjectKey();
        }
        this.table().inserts(arr);
    }
}